//
// Created by tcj on 2021/12/10.
//
#include "config.h"

namespace sylar{

    ConfigVarBase::ptr Config::LookupBase(const std::string &name) {
        RWMutexType::ReadLock lock(GetMutex());
        auto it = GetDatas().find(name);
        return it == GetDatas().end()? nullptr:it->second;
    }
    //"A.B",10
    //A:
    //  B: 10
    //  C:str

    static void ListAllMember(const std::string& prefix,const YAML::Node& node,
                              std::list<std::pair<std::string,const YAML::Node> >& output){
        if(prefix.find_first_not_of("abcdefghijklmnopqrstuvwxyz._0123456789") != std::string::npos){
            SYLAR_LOG_ERROR(SYLAR_LOG_ROOT())<<"config invaild name: "<<prefix<<" : "<<node;
        }
        output.push_back(std::make_pair(prefix,node));
        if(node.IsMap()){
            for(auto it=node.begin();it!=node.end();it++){
                ListAllMember(prefix.empty() ? it->first.Scalar() : prefix+"."+it->first.Scalar(),it->second,output);
            }
        }
    }

    //加载yaml中配置
    void Config::LoadFormYaml(const YAML::Node &root) {
        std::list<std::pair<std::string,const YAML::Node>> all_node;
        ListAllMember("",root,all_node);
//        for(auto & single_node:all_node){
//            std::cout<<single_node.first<<"=-----="<<single_node.second<<std::endl;
//        }
        for(auto& i :all_node){
            std::string key = i.first;
            if(key.empty()){
                continue;
            }
            std::transform(key.begin(),key.end(),key.begin(),::tolower);
            ConfigVarBase::ptr var = LookupBase(key);

            if(var){
                if(i.second.IsScalar()){
                    var->fromString(i.second.Scalar());
                }else{
                    std::stringstream ss;
                    ss<<i.second;
                    var->fromString(ss.str());
                }
            }
        }

    }

    void Config::Visit(std::function<void(ConfigVarBase::ptr)> cb) {
        RWMutexType::ReadLock lock(GetMutex());
        ConfigVarMap& m =  GetDatas();
        for(auto  it=m.begin();it!=m.end();++it){
            cb(it->second);
        }
    }
}
